/**
 * QUANSHI.com Inc.
 * Copyright (c) 2016-2017 All Rights Reserved.
 */
package com.quanshi.scheduler.job.biz.quartz.monitor;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.quanshi.scheduler.core.base.RegistryConfig;
import com.quanshi.scheduler.job.biz.quartz.JobDynamicScheduler;
import com.quanshi.scheduler.job.dal.entity.TriggerRegistry;

/**
 * 
 * @author yanxiang.huang 2017-07-10 16:04:46
 */
public class JobRegistryMonitor
{
    
    private static Logger logger = LoggerFactory.getLogger(JobRegistryMonitor.class);

    private static JobRegistryMonitor instance = new JobRegistryMonitor();
    
    private JobRegistryMonitor() {}
    
    public static JobRegistryMonitor getInstance(){
        return instance;
    }

    private ConcurrentHashMap<String, List<String>> registMap = new ConcurrentHashMap<String, List<String>>();

    private Thread registryThread;
    private boolean toStop = false;
    public void start(){
        registryThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!toStop) {
                    try {
                        // remove dead admin/executor
                        JobDynamicScheduler.triggerRegistryService.removeDead(RegistryConfig.DEAD_TIMEOUT);

                        // fresh registry map
                        ConcurrentHashMap<String, List<String>> temp = new ConcurrentHashMap<String, List<String>>();
                        List<TriggerRegistry> list = JobDynamicScheduler.triggerRegistryService.findAll(RegistryConfig.DEAD_TIMEOUT);
                        if (list != null) {
                            for (TriggerRegistry item: list) {
                                String groupKey = makeGroupKey(item.getRegistryGroup(), item.getRegistryKey());
                                List<String> registryList = temp.get(groupKey);
                                if (registryList == null) {
                                    registryList = new ArrayList<String>();
                                }
                                if (!registryList.contains(item.getRegistryValue())) {
                                    registryList.add(item.getRegistryValue());
                                }
                                temp.put(groupKey, registryList);
                            }
                        }
                        registMap = temp;
                    } catch (Exception e) {
                        logger.error("job registry instance error:{}.", e);
                    }
                    try {
                        TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
                    } catch (InterruptedException e) {
                        logger.error("job registry instance error:{}", e);
                    }
                }
            }
        });
        registryThread.setDaemon(true);
        registryThread.start();
    }

    public void toStop(){
        toStop = true;
    }
    
    public static List<String> discover(String registryGroup, String registryKey){
        String groupKey = makeGroupKey(registryGroup, registryKey);
        return instance.registMap.get(groupKey);
    }

    private static String makeGroupKey(String registryGroup, String registryKey){
        return registryGroup.concat("_").concat(registryKey);
    }
    
}
